#include "StdAfx.h"
#include "network.h"


int TCPSOCKET;
char* SOCKET_ADDRESS = "127.0.0.1";
int SOCKET_PORT = 4444;

#using <mscorlib.dll>
using namespace System;
using namespace System::Threading;
 // Simple threading scenario:  Start a Shared method running
 // on a second thread.
public __gc class ThreadExample {
 public:
     // The ThreadProc method is called when the thread starts.
     // It loops ten times, writing to the console and yielding 
     // the rest of its time slice each time, and then ends.
     static void ThreadProc()
     {
		 while(true) {
			 readFrameFromNetwork(FRAME_DATA, FRAME_WIDTH, FRAME_HEIGHT);
		 }
     }
 };



void setupNetwork() {

		// Fire up WinSock
	WSAData wsaData;
	int nCode;

	if ((nCode = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0) {
		printf("\nWSAStartup error %i\n", nCode);
	}


	TCPSOCKET = call_socket(SOCKET_ADDRESS, SOCKET_PORT);

	Thread *oThread = new Thread(new ThreadStart(0, &ThreadExample::ThreadProc));
 
     // Start the thread.  On a uniprocessor, the thread does not get 
     // any processor time until the main thread yields.  Uncomment
     // the Thread.Sleep that follows t.Start() to see the difference.
     oThread->Start();
     //oThread->Join();

}

void cleanupNetwork() {
	
	// Shut Winsock back down and take off.
	WSACleanup();
}


// http://www.frostbytes.com/~jimf/papers/sockets/sockets.html
int read_data(int s,     /* connected socket */
			  char *buf, /* pointer to the buffer */
			  int n      /* number of characters (bytes) we want */
			  )
{ 
	recv(s, buf, n, 0);
	return n;
}

// http://www.frostbytes.com/~jimf/papers/sockets/sockets.html
int call_socket(char *hostname, unsigned short portnum) { 
	struct sockaddr_in sa;
	struct hostent     *hp;
	int s;

	if ((hp = gethostbyname(hostname)) == NULL) { /* do we know the host's */
		return -1;                                /* no */
	}

	memset(&sa,0,sizeof(sa));
	memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length);     /* set address */
	sa.sin_family = hp->h_addrtype;
	sa.sin_port = htons((u_short)portnum);

	if ((s = socket(hp->h_addrtype,SOCK_STREAM,0)) < 0)     /* get socket */
		return -1;
	if (connect(s,(struct sockaddr *)&sa,sizeof sa) < 0) { /* connect */
		closesocket(s);
		return -1;
	}
	return s;
}

void readFrameFromNetwork(char* c, int width, int height) {
	char dimensions[6];
	read_data(TCPSOCKET, dimensions, 5);

	read_data(TCPSOCKET, dimensions, 1); // swallow newline
	read_data(TCPSOCKET, c, width*height);

	// Dynamically allocate array - required to build on Win32
	// http://www.eskimo.com/~scs/cclass/int/sx9b.html

	read_data(TCPSOCKET, c, 1); // swallow newline
}

// Command server to recalibrate - just sending any string will do
void recalibrateVision(void) {
	send(TCPSOCKET, "r", 2,0);
}